/*******************************************************************************************************************************************************************
                                                                 
																 //////////////////////限幅滤波算法//////////////////////////

1.方法：限幅滤波算法也称为"程序判断滤波"。生产经验告诉我们，很多物理量的变化是需要一定时间的(即数学模型中包含惯性环节)，相邻两次采样值之间的变化有一个合理的限度(即有用信号高频分量的最高频率有限)。例如在热处理车间的大型电炉里，工件的温度变化不可能在短时间(采样间隔)内发生剧烈变化，如果相邻两次采样值之间的变化未超过预定的范围，说明该采样值未受到明显干扰(毛刺性突发干扰)，可以采信。如果相邻两次采样值之间的变化超过了预定的范围，说明该采样值受到了明显干扰，不能采信。对于不可信的采样数据，必须输出一个合理的替代数据，以保证采样数据序列的连续性和完整性。在要求不高的场合，可以用前一个采样数据来替代这个受干扰的采样数据。
		
2.例程：
		(1)调用函数
		(2)变量说明：
		(3)常量说明：
		(4)入口：
		(5)出口：

********************************************************************************************************************************************************************/

#define D 10            //相邻两次采样值之间最大允许变化值

unsigned int history;   //上次采样值

unsigned int AmplitudeLimterFilter()
{
	unsigned int new;
	
	new = SampleAdc();     //进行一次采样，得到当前的A/D转换值
	
	if (((new - history) > D) || ((history - new) > D))
	{
		new = history;          //如果变化超过允许范围，以前一次采样值作为当前采样值
	}
	else
	{
		history = new;          //如果变化在合理范围，则更新上次采样值，并为下一次采样准备好"比较基准"
	}
	
	return new;              
}

/********************************************************************************************************************************************************************
                                                                 
																 //////////////////////"改进型"限幅滤波算法//////////////////////////

1.方法：当被检测物理量处于明显变化阶段时，相邻两个采样之间的差别也比较明显，这时用前一个采样值来替代当前受干扰的采样值必然存在较大误差，因此，可以利用被检测物理量的变化趋势来进行预测，选择一个更加合理的数据来替代当前受干扰的采样值，是的替代误差大大减小。
		为了找我被检测物理量当前的变化趋势，至少需要有两个以上的采样值历史记录。我们采用最简单的线性预测算法，只要两个历史采样值就可以了。线性预测算法的含义为"当前采样值的变化趋势与
前一次采样值的变化趋势相同"，及采样值在短期内保持相同的上升趋势或下降趋势。设相邻3次采样值一次为X0、X1和X2，则有：
																		X2 - X1 = X1 - X0
																   ==>  X2 = 2X1 -X0
		即由两个历史采样值X0和X1可以预测出当前的采样值X2，用这个采样值代替受干扰的当前采样值会更加合理。
		
2.例程：
		(1)调用函数
		(2)变量说明：
		(3)常量说明：
		(4)入口：
		(5)出口：


********************************************************************************************************************************************************************/

#define D 10                //相邻两次采样值之间最大允许变化值
unsigned int history[2];    //history[1]为最近一次采样值,history[0]为更早一次的采样值

unsigned int AmplitudeLimterFilter()
{
	int new;
	new = SampleAdc();
	
	if (((new - history[1]) > D) || ((history[1] - new) > D))
	{
		//如果变化超过允许范围，则按趋势进行预测
		new = 2*history[1] - history[0];
		
		if (new < 0)
		{
			new = 0;          //A/D转换值不能为负数
		}
		
		if (new >4095)
		{
			new = 4095;       //12位A/D转换值不能超过4095
		}
	}
	
	//进行数据更新
	history[0] = history[1];
	history[1] = new;
	
	return new;
}

/********************************************************************************************************************************************************************
                                                                
																//////////////////////"改进型"限幅滤波算法例程//////////////////////////

1.方法：假设某温度控制系统的控制范围是1~100℃，控制精度为0.5℃。采用12位A/D转换芯片，空间分辨率达到了100/4095 = 0.025℃，完全满足0.5℃控制精度的要求。再假设控制对象的最大温度变化速率为0.25℃/s，即0.5℃/2s为了满足时间分辨率要求，相邻两次采样之间的时间间隔(采样周期)不得超过2s，如果超过了2s，则温度变化超过了0.5℃，此时则满足不了0.5℃的控制精度的要求。为了留有充分余地，采样周期可选择为0.5s,使得采样时间分辨率更高一些("高频特性"好一些)，控制精度更有保障。另外一方面，采样周期也不能太短，必须大于干扰的持续时间，以免一次干扰造成两次以上的采样值不准确。假设每次干扰的持续时间不超过0.2s(4个工频周期)，在这里0.5s的采样周期大于0.2s的干扰的持续时间，故采样周期为0.5s是合理的。在这个例子中，温度最大变化速率就是有用信号高频分量的体现，控制精度就是系统对高频特性要求的体现，满足了这两方面的要求，实际上就是满足了奈奎斯特采样定律。

		在0.5s的采样时间间隔里，温度醉倒变化0.125℃，相当于A/D转换值最多变化5，为了留有余地，将相邻两次采样值之间最大允许变化值选择为10
		
2.例程：
		(1)调用函数
		(2)变量说明：
		(3)常量说明：
		(4)入口：
		(5)出口：
********************************************************************************************************************************************************************/

#define D 10
int history[2];

void TaskSampleCtrl(void * pdata)
{
	int new;
	
	history[0] = SampleAdc();
	OSTimeDly(25);
	history[1] = SampleAdc();
	OSTimeDly(25);
	
	while (1)
	{
		new = SampleAdc();
		
		if (((new - history[1]) > D) || ((history[1] - new) > D))
		{
			new = 2*history[1] - history[0];
			
			if (new < 0)
			{
				new = 0;
			}
			
			if (new >4095)
			{
				new = 4095;
			}
		}
			
		history[0] = history[1];
		history[1] = new;
		TempCtrl();
		OSTimeDly(25);
	}
	
}






